package com.lt.flashcard.view;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.zkoss.xel.fn.StringFns;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Path;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.A;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Div;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.Flashcard;
import com.lt.flashcard.model.entity.FlashcardSet;
import com.lt.flashcard.model.entity.User;
import com.lt.flashcard.model.service.FlashcardService;
import com.lt.flashcard.model.service.FlashcardSetService;
import com.lt.flashcard.model.service.Repository;

/**
 * Render the word list detail showcase page
 * @author NNNguyen
 * @version 1.0
 */
public class V_WordlistDetailShowcaseListCtrl extends SelectorComposer<Component> {

    private static final long serialVersionUID = 1L;
    private boolean canEdit = false;
    private boolean isAdmin = true;
    private boolean isBuy = false;
    private boolean isLogin = false;

    public boolean getAllowedEdit() {
        return ctrl.isAllowedEdit();
    }

    public FlashcardSet getFlashcardset() {
        return ctrl.getFlashcardset();
    }

    public List<Flashcard> getFlashcards() {
        Clients.evalJavaScript("$.calculateTerm()");
        return flashcardset.getFlashcards();
    }

    @Listen("onClick=.bin_card_small")
    public void deleteFlashcard(Event event) {
        if (!isOwner()) {
            return;
        }
        A a = (A) event.getTarget();
        Long id = (Long) a.getAttribute("id");
        Flashcard fc = flashcardset.getFlashcardById(id);
        if (fc != null) {
            FlashcardService fcsrv = Repository.getInstance().getFlashcardService();
            FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
            flashcardset.removeFlashcard(fc);
            fcsrv.delete(fc);
            fsSrv.save(flashcardset);
            ctrl.grid_flashcards.invalidate();
            ctrl.list_flashcards.invalidate();
        }
    }

    /**
     * created by Nguyen Trung Tam
     * created date: 31/10/2012
     */

    @Wire(".chkFlashcards")
    private List<Checkbox> chkFlashcards;
    private WordlistDetailMainCtrl ctrl;
    private FlashcardSet flashcardset;
    private Flashcard flashcard;

    @Wire
    Checkbox g_chkAll;
    @Wire
    Textbox g_name_set;
    @Wire
    Textbox description_set;
    @Wire
    Textbox tags_set;
    @Wire
    Listbox g_list_set;
    @Wire
    A delFlashcardsSelected;
    @Wire
    Div action_top;
    @Wire
    A list;
    @Wire
    A grid;

    @Override
    public void doBeforeComposeChildren(Component comp) throws Exception {
        super.doBeforeComposeChildren(comp);
        Component com = Path.getComponent("//page_wordlist_detail/wordlist_detail_main");
        ctrl = (WordlistDetailMainCtrl) com.getAttribute("$composer");
        flashcardset = ctrl.getFlashcardset();
        canEdit = ctrl.isAllowedEdit();
        isAdmin = flashcardset.getAdmin() != FlashcardSet.ADMIN_NO;
        isBuy = flashcardset.getAdmin() == FlashcardSet.ADMIN_BUY || flashcardset.getAdmin() == FlashcardSet.ADMIN_YES;
        setLogin(Utility.isLogin());
    };

    public ListModelList<FlashcardSet> getFlashcardsets() {
        FlashcardSetService srv = Repository.getInstance().getFlashcardSetService();
        List<FlashcardSet> flashcardsets = srv.getFlashcardsetsOfCurrUser(Utility.getUser(), true);
        return new ListModelList<FlashcardSet>(flashcardsets);
    }

    public List<Checkbox> getLchkFlashcards() {
        if (chkFlashcards == null) {
            chkFlashcards = new ArrayList<Checkbox>();
        }
        return chkFlashcards;
    }

    /**
     * Check all
     */
    @Listen("onCheck=#g_chkAll")
    public void checkAll(CheckEvent e) {
        for (Checkbox chk : chkFlashcards) {
            chk.setChecked(e.isChecked());
        }
        Clients.evalJavaScript("$('.content_wdsl :checkbox').uniform();");
        Clients.evalJavaScript("$.countChecked();");
    }

    private boolean checkPermision() {
        if (Repository.getInstance().getAAService().isLogin()) {
            if (!flashcardset.getAuthor().getId().equals(Utility.getUser().getId())) {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    @Listen("onClick=#delFlashcardsSelected")
    public void deleteFlashcardsSelected() {
        if (isOwner()) {
            FlashcardService fSrv = Repository.getInstance().getFlashcardService();
            FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
            int counter = 0;
            for (Checkbox chk : chkFlashcards) {
                if (chk.isChecked()) {
                    Long id = chk.getValue();
                    Flashcard fc = flashcardset.getFlashcardById(id);
                    if (fc != null) {
                        flashcardset.removeFlashcard(fc);
                        fSrv.delete(fc);
                        counter++;
                    }
                }
            }
            if (counter > 0) {
                fsSrv.save(flashcardset);
                ctrl.grid_flashcards.invalidate();
                ctrl.list_flashcards.invalidate();
            }
        }
    }

    @Listen("onClick=.add_small")
    public void addFlashcardIntoSet(Event event) {
        if (!isLogin()) {
            Clients.evalJavaScript("showNotice('','Bạn phải login để thực hiện chức năng này')");
            return;
        }
        A a = (A) event.getTarget();
        Flashcard fc = (Flashcard) a.getAttribute("flashcard");
        this.flashcard = fc;
    }

    /**
     * Copy list of flashcards to own flashcardset
     */
    @Listen("onClick=#g_save_flashcards_into_set")
    public void saveIntoFlashcardSet() {
        FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
        if (this.flashcard != null) {// one flashcard is selected
            if (fsSrv.enoughBlankFlashcard(1)) {
                if (g_list_set.getSelectedItem() == null) {
                    Clients.evalJavaScript("showNotice('','Vui lòng chọn một flashcard set!')");
                    return;
                }

                FlashcardSet setSelected = g_list_set.getSelectedItem().getValue();

                if (setSelected.isTermExist(flashcard.getTerm())) {
                    Clients.evalJavaScript("showNotice('', 'Flashcard bị trùng')");
                    return;
                }

                Flashcard insertFlashcard = flashcard.clone();
                setSelected.addFlashcard(insertFlashcard);
                fsSrv.save(setSelected);
                flashcard = null;
                Clients.evalJavaScript("showNotice('', 'Hoàn tất')");
            } else {
                Clients.evalJavaScript("showNotice('', 'Bạn không đủ số flashcard trắng. Vui lòng mua thêm!')");
            }
        } else { // save flashcards selected into another set
            List<Flashcard> fcs = new ArrayList<Flashcard>();
            for (Checkbox chk : chkFlashcards) {
                if (chk.isChecked()) {
                    Long id = chk.getValue();
                    Flashcard fc = flashcardset.getFlashcardById(id);
                    if (fc != null) {
                        fcs.add(fc);
                    }
                }
            }
            if (fcs.size() == 0) {
                Clients.evalJavaScript("showNotice('', 'Bạn chưa chọn flashcard')");
                return;
            }
            if (!fsSrv.enoughBlankFlashcard(fcs.size())) {
                Clients.evalJavaScript("showNotice('', 'Bạn không có đủ " + fcs.size() + " flashcard trắng')");
                return;
            }
            Listitem sl = g_list_set.getSelectedItem();
            FlashcardSet setSelected = (FlashcardSet) (sl == null ? null : sl.getValue());
            if (setSelected == null) {
                Clients.evalJavaScript("showNotice('','Vui lòng chọn một flashcard set!')");
                return;
            }
            List<String> dupplicated = new ArrayList<String>();// Dupplicated term
            int success = 0;
            for (Flashcard fc : fcs) {
                if (setSelected.isTermExist(fc.getTerm())) {
                    dupplicated.add(fc.getTerm());
                    continue;
                }

                Flashcard insertFlashcard = fc.clone();
                setSelected.addFlashcard(insertFlashcard);
                success += 1;
            }
            if (success > 0) {
                fsSrv.save(setSelected);
            }
            String fail = StringFns.join(dupplicated.toArray(), ", ");
            if (fail.length() > 0) {
                Clients.evalJavaScript("showNotice('', 'Hoàn tất! Các card sau bị trùng: " + fail + "')");
            } else if (success > 0) {
                Clients.evalJavaScript("showNotice('', 'Hoàn tất!')");
            }
        }
    }

    // create new flashcard set with name typed and save flashcard(s) are seleted into new flashcard set
    @Listen("onClick=#g_create_set")
    public void createAndSaveFlashcardSet() {
        FlashcardSetService fsSrv = Repository.getInstance().getFlashcardSetService();
        if (Utility.isEmptyString(g_name_set.getValue())) {
            Clients.evalJavaScript("showNotice('','Vui lòng nhập tên flashcard set');");
            return;
        }
        User user = Utility.getUser();
        if (flashcard != null) {// one flashcard is selected
            if (user.getCurrentblankflashcard() < 1) {
                Clients.evalJavaScript("showNotice('','Không đủ flashcard trắng');");
                return;
            }
            FlashcardSet newSet = new FlashcardSet();
            newSet.setName(g_name_set.getValue());
            newSet.setAuthor(user);
            newSet.setDescription(description_set.getValue());
            if (!Utility.isEmptyString(tags_set.getValue())) {
                newSet.addTags(Arrays.asList(tags_set.getValue().split(",")));
            }

            Flashcard insertFlashcard = flashcard.clone();
            newSet.addFlashcard(insertFlashcard);

            fsSrv.save(newSet);

            Executions.sendRedirect("/flashcard.zul?task=edit&id=" + newSet.getId().toString());
        } else {
            // fsSrv.createSetAndAddFlashcardsIntoSet(chkFlashcards, flashcardset, g_name_set.getValue());
            ArrayList<Long> ids = new ArrayList<Long>();
            for (Checkbox ck : chkFlashcards) {
                if (ck.isChecked()) {
                    ids.add((Long) ck.getValue());
                }
            }

            if (ids.size() > 0) {
                if (user.getCurrentblankflashcard() < ids.size()) {
                    Clients.evalJavaScript("showNotice('','Không đủ flashcard trắng');");
                    return;
                }
                FlashcardSet newSet = new FlashcardSet();
                newSet.setName(g_name_set.getValue());
                newSet.setAuthor(user);
                newSet.setDescription(description_set.getValue());
                if (!Utility.isEmptyString(tags_set.getValue())) {
                    newSet.addTags(Arrays.asList(tags_set.getValue().split(",")));
                }
                fsSrv.copyFlashcards(flashcardset, ids, newSet);
                fsSrv.save(newSet);

                Executions.sendRedirect("/flashcard.zul?task=edit&id=" + newSet.getId().toString());
            } else {
                Clients.evalJavaScript("showNotice('','Bạn chưa chọn flashcard');");
            }
        }
    }

    /**
     * edit flashcards
     */
    @Listen("onClick=#editFlashcardsSelected")
    public void doEditSelected() {
        if (isOwner()) {
            List<String> ids = new ArrayList<String>();
            for (Checkbox chk : chkFlashcards) {
                if (chk.isChecked()) {
                    ids.add(String.valueOf(chk.getValue()));
                }
            }
            if (ids.size() > 0) {
                String u = StringFns.join(ids.toArray(), ",");
                Utility.redirect(Utility.removeContextPath(Utility.generateUrl("editflashcardset", flashcardset.getId(), "fcids=" + u)), true);
            } else {
                Clients.evalJavaScript("showNotice('', 'Bạn chưa chọn flashcard')");
            }
        } else {
        }
    }

    /**
     * edit each flashcard in the card showcase
     */
    @Listen("onClick=.edit")
    public void doEditFlashcard(Event event) {
        Long id = (Long) event.getTarget().getAttribute("id");
        Flashcard fc = flashcardset.getFlashcardById(id);
        if (fc != null) {
            Utility.redirect(Utility.removeContextPath(Utility.generateUrl("editflashcardset", flashcardset.getId(), "fcids=" + id)), true);
        }
    }

    @Listen("onClick=#list")
    public void doDisplayList() {
        ctrl.listOrGrid(true);
    }

    @Listen("onClick=#grid")
    public void doDisplayGrid() {
        ctrl.listOrGrid(false);
    }

    @Listen("onClick=.select_small")
    public void updateStatusChkAll() {
        // TODO optimize this
        int count = 0;
        for (Checkbox chk : chkFlashcards) {
            if (chk.isChecked()) {
                count++;
            }
        }
        if (count == chkFlashcards.size()) {
            g_chkAll.setChecked(true);
        } else {
            g_chkAll.setChecked(false);
        }
        Clients.evalJavaScript("$('.content_wdsl :checkbox').uniform();");
        flashcard = null;
    }

    public boolean isOwner() {
        FlashcardSetService fcsrv = Repository.getInstance().getFlashcardSetService();
        return fcsrv.checkOwnFlashcardSet(Utility.getUser(), flashcardset);
    }

    public boolean isCanEdit() {
        return canEdit;
    }

    public void setCanEdit(boolean canEdit) {
        this.canEdit = canEdit;
    }

    /**
     * @return the isAdmin
     */
    public boolean isAdmin() {
        return isAdmin;
    }

    /**
     * @param isAdmin the isAdmin to set
     */
    public void setAdmin(boolean isAdmin) {
        this.isAdmin = isAdmin;
    }

    public boolean isBuy() {
        return isBuy;
    }

    public void setBuy(boolean isBuy) {
        this.isBuy = isBuy;
    }

    /**
     * @return the isLogin
     */
    public boolean isLogin() {
        return isLogin;
    }

    /**
     * @param isLogin the isLogin to set
     */
    public void setLogin(boolean isLogin) {
        this.isLogin = isLogin;
    }
}
